不是PE文件, 直接拖进IDA
分析, F5查看伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { int v3; char v4;
while ( 1 ) { while ( 1 ) { printf("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: "); v4 = getchar(); if ( v4 != 100 && v4 != 68 ) break; Decry(); } if ( v4 == 113 || v4 == 81 ) Exit("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: ", argv); puts("Input fault format!"); v3 = getchar(); putchar(v3); } }
|
Decry()
函数长这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| unsigned __int64 Decry() { char v1; int v2; int v3; int i; int v5; char src[8]; __int64 v7; int v8; __int64 v9[2]; int v10; unsigned __int64 v11;
v11 = __readfsqword(0x28u); *(_QWORD *)src = 0x534C43444ELL; v7 = 0LL; v8 = 0; v9[0] = 0x776F646168LL; v9[1] = 0LL; v10 = 0; text = (char *)join(key3, v9); strcpy(key, key1); strcat(key, src); v2 = 0; v3 = 0; getchar(); v5 = strlen(key); for ( i = 0; i < v5; ++i ) { if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) key[i] = key[v3 % v5] + 32; ++v3; } printf("Please input your flag:"); while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } } else { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } if ( !(v3 % v5) ) putchar(32); ++v2; } } if ( !strcmp(text, str2) ) puts("Congratulation!\n"); else puts("Try again!\n"); return __readfsqword(0x28u) ^ v11; }
|
主要就是逆向这一段, 得出v1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } } else { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } if ( !(v3 % v5) ) putchar(32); ++v2; } }
|
写出解密脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <cstdio> #include <cstring>
using namespace std;
int main() { char key[16] = "adsfkndcls"; char ciphertext[16] = "killshadow"; char plaintext[16] = { 0 }; char key_offset = 0; for (int i = 0; i < strlen(ciphertext); i++) for (char c = 32; c < 127; c++) { char temp = c; if (('a' <= c && c <= 'z') or ('A' <= c && c <= 'Z')) temp = (c - 39 - key[key_offset % strlen(key)] + 97) % 26 + 97; if (temp == ciphertext[i]) { plaintext[i] = c; key_offset++; break; } } printf("%s", plaintext); }
|
所以flag就是flag{KLDQCUDFZO}